package com.party.admin.web.controller.notify;

import com.google.common.collect.Lists;
import com.party.admin.biz.notify.SysMessageBizService;
import com.party.admin.web.dto.AjaxResult;
import com.party.admin.web.dto.input.common.CommonInput;
import com.party.admin.web.dto.output.system.MemberOutput;
import com.party.common.paging.Page;
import com.party.common.utils.DateUtils;
import com.party.common.utils.Html2Text;
import com.party.common.utils.LangUtils;
import com.party.common.utils.StringUtils;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.notify.NotifySysMessage;
import com.party.core.model.notify.NotifySysMessageMember;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.notify.INotifySysMessageMemberService;
import com.party.core.service.notify.INotifySysMessageService;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import java.text.ParseException;
import java.util.*;

/**
 * 系统消息推送
 *
 * @author yifeng
 * @date 2018/6/25 0025
 * @time 下午 15:23
 */
@Controller
@RequestMapping("notify/sysMessage")
public class SysMessageController {
    @Autowired
    private INotifySysMessageService notifySysMessageService;
    @Autowired
    private INotifySysMessageMemberService notifySysMessageMemberService;
    @Autowired
    private SysMessageBizService sysMessageBizService;
    @Autowired
    private IMemberGroupService memberGroupService;

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 消息列表
     *
     * @param sysMessage  消息
     * @param commonInput 查询条件
     * @param page        分页
     * @return
     */
    @RequestMapping("webListPage")
    public ModelAndView list(NotifySysMessage sysMessage, CommonInput commonInput, Page page) {
        page.setLimit(20);
        ModelAndView mv = new ModelAndView("notify/sysMessageList");
        Map<String, Object> params = CommonInput.appendParams(commonInput);
        params.put("sendStatus", sysMessage.getSendStatus());
        sysMessage.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
        List<NotifySysMessage> sysMessages = notifySysMessageService.webListPage(sysMessage, params, page);

        for (NotifySysMessage output : sysMessages) {
            if (output.getSendTime().getTime() > System.currentTimeMillis()) {
                output.setSendStatus(YesNoStatus.NO.getCode());
            } else {
                output.setSendStatus(YesNoStatus.YES.getCode());
            }

            if (StringUtils.isNotEmpty(output.getContent())) {
                String content = StringEscapeUtils.unescapeHtml4(output.getContent());
                String newContent = Html2Text.getContent(content);
                output.setContent(newContent);
            }
        }
        mv.addObject("messageList", sysMessages);
        mv.addObject("page", page);
        mv.addObject("input", commonInput);
        mv.addObject("sysMessage", sysMessage);
        return mv;
    }

    /**
     * 新增/编辑页面
     *
     * @param id 消息id
     * @return
     */
    @RequestMapping("toForm")
    public ModelAndView toForm(String id) {
        ModelAndView mv = new ModelAndView("notify/sysMessageForm");
        if (StringUtils.isNotEmpty(id)) {
            NotifySysMessage notifySysMessage = notifySysMessageService.get(id);
            mv.addObject("sysMessage", notifySysMessage);
        }
        return mv;
    }

    /**
     * 保存消息
     *
     * @param sysMessage     消息
     * @param result         验证结果
     * @param memberList     推送对象
     * @param sendTimeString 推送时间
     * @return
     */
    @ResponseBody
    @RequestMapping("save")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult save(NotifySysMessage sysMessage, BindingResult result, String memberList, String sendTimeString) {
        if (result.hasErrors()) {
            List<ObjectError> allErrors = result.getAllErrors();
            return AjaxResult.error(allErrors.get(0).getDefaultMessage());
        }
        if (sysMessage.getIsPushAll().equals(YesNoStatus.NO.getCode()) && StringUtils.isEmpty(memberList)) {
            return AjaxResult.error("推送对象不能为空");
        }
        if (StringUtils.isEmpty(sendTimeString)) {
            return AjaxResult.error("推送时间不能为空");
        }
        try {
            if (sendTimeString.indexOf(":") == sendTimeString.lastIndexOf(":")) {
                sendTimeString = sendTimeString + ":00";
            }
            Date sendTime = DateUtils.parse(sendTimeString, "yyyy-MM-dd HH:mm:ss");
            sysMessage.setSendTime(sendTime);
            sysMessageBizService.saveBiz(sysMessage, Arrays.asList(memberList.split(",")), sendTime);
            return AjaxResult.success();
        } catch (ParseException e) {
            return AjaxResult.error("定时推送短信失败, 时间参数有误 " + sendTimeString);
        } catch (Exception e) {
            logger.error("推送失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("推送失败");
        }
    }

    /**
     * 获取已经选择的合作商
     *
     * @param memberIds    用户ids 逗号隔开
     * @param sysMessageId 系统消息id
     * @return
     */
    @ResponseBody
    @RequestMapping("findByMessageId")
    public AjaxResult findByMessageId(String memberIds, String sysMessageId) {
        if (StringUtils.isNotEmpty(memberIds) || StringUtils.isNotEmpty(sysMessageId)) {
            List<MemberGroup> members = Lists.newArrayList();
            if (StringUtils.isNotEmpty(memberIds)) {
                members = memberGroupService.batchList(new HashSet<>(Arrays.asList(memberIds.split(","))), null, null);
            } else if (StringUtils.isNotEmpty(sysMessageId)) {
                NotifySysMessage sysMessage = notifySysMessageService.get(sysMessageId);
                if (sysMessage.getIsPushAll().equals(YesNoStatus.YES.getCode())) {
                    return AjaxResult.success(new ArrayList<MemberOutput>());
                }
                List<NotifySysMessageMember> messageMembers = notifySysMessageMemberService.findByMessageId(sysMessageId);
                List<String> memberIdList = LangUtils.transform(messageMembers, input -> input.getMemberId());
                members = memberGroupService.batchList(new HashSet<>(memberIdList), null, null);
            }
            List<MemberOutput> memberOutputs = LangUtils.transform(members, input -> {
                MemberOutput output = new MemberOutput();
                output.setId(input.getId());
                output.setRealname(input.getRealname());
                return output;
            });
            return AjaxResult.success(memberOutputs);
        }
        return AjaxResult.success(new ArrayList<MemberOutput>());
    }

    /**
     * 逻辑删除消息
     *
     * @param id 消息id
     * @return
     */
    @ResponseBody
    @RequestMapping("deleteLogic")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult deleteLogic(String id) {
        if (StringUtils.isEmpty(id)) {
            return AjaxResult.error("id不能为空");
        }
        try {
            sysMessageBizService.deleteQuartz(id);
            return AjaxResult.success();
        } catch (Exception e) {
            return AjaxResult.error("删除失败");
        }
    }

    /**
     * 再次推送
     *
     * @param sysMessage 消息
     * @param memberList 推送对象
     * @return
     */
    @ResponseBody
    @RequestMapping("sendAgain")
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public AjaxResult sendAgain(NotifySysMessage sysMessage, String memberList) {
        if (StringUtils.isEmpty(sysMessage.getId())) {
            return AjaxResult.error("消息id不能为空");
        }
        if (sysMessage.getIsPushAll().equals(YesNoStatus.NO.getCode()) && StringUtils.isEmpty(memberList)) {
            return AjaxResult.error("推送对象不能为空");
        }
        try {
            sysMessageBizService.saveSendAgainBiz(sysMessage, Arrays.asList(memberList.split(",")));
            return AjaxResult.success();
        } catch (Exception e) {
            logger.error("推送失败", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error("推送失败");
        }
    }
}
